use md5::{Digest, Md5};
use serde_json::{json, Value};
use std::collections::{BTreeMap, HashMap};
use std::time::{SystemTime, UNIX_EPOCH};

fn get_md5_hash(input: &str) -> String {
    let mut hasher = Md5::new();
    hasher.update(input);
    let result = hasher.finalize();
    format!("{:X}", result)
}

pub fn get_salt_md5(input: &str) -> String {
    let salt = get_md5_hash(input);
    let mut chars: Vec<char> = salt.chars().collect();
    chars.swap(8, 16);
    chars.swap(18, 21);
    chars.iter().collect()
}

fn sign(app_key: &str, params: &HashMap<String, String>) -> String {
    // 创建一个 BTreeMap 来存储排序后的参数
    let mut sorted_params = BTreeMap::new();
    for (key, value) in params.iter() {
        sorted_params.insert(key.clone(), value.clone());
    }

    // 创建 StringBuilder 来拼接字符串
    let mut sb = format!("{}", app_key);

    // 遍历参数并拼接
    for (key, value) in sorted_params.iter() {
        if value.is_empty() || key.to_lowercase() == "_sign" || key.to_lowercase() == "sign" {
            continue;
        }
        sb.push_str(key);
        sb.push_str(value);
    }

    // 再次添加 app_key
    sb.push_str(app_key);

    // 生成 MD5 哈希值并转换为大写
    let mut hasher = Md5::new();
    hasher.update(sb);
    let result = hasher.finalize();
    format!("{:X}", result)
}

fn get_timestamp_millis() -> u128 {
    match SystemTime::now().duration_since(UNIX_EPOCH) {
        Ok(duration) => duration.as_millis(),
        Err(_) => 0, // 处理可能的错误情况
    }
}

pub fn get_signature() -> Value {
    let app_key = "r/F1C41WHWPs1qCdSo+kNY3skBVCC5cl";
    let timestamp = get_timestamp_millis();
    let mut params = json!({
        "_appid": "developer_io",
        "_timestamp": timestamp.to_string(),
    });
    let params_map: HashMap<String, String> = params
        .as_object()
        .unwrap()
        .iter()
        .map(|(k, v)| (k.clone(), v.as_str().unwrap_or("").to_string()))
        .collect();
    let signature = sign(app_key, &params_map);
    params["_sign"] = json!(signature);
    params
}
#[test]
fn sign_get_salt_md5() {
    let md5_str = get_md5_hash("legend");
    println!("{:?}", md5_str);
    let s = get_salt_md5("legend");
    println!("{:?}", s)
}
